from enum import Enum

from pydantic import BaseModel, Field, field_validator

from internal.exception.exception import ValidateErrorException


class ParameterType(str, Enum):
    """参数支持的类型"""
    STR: str = "str"
    INT: str = "int"
    FLOAT: str = "float"
    BOOL: str = "bool"


class ParameterIn(str, Enum):
    """参数支持存放的位置"""
    PATH: str = "path"
    QUERY: str = "query"
    HEADER: str = "header"
    COOKIE: str = "cookie"
    REQUEST_BODY: str = "request_body"


ParameterTypeMap = {
    ParameterType.STR: str,
    ParameterType.INT: int,
    ParameterType.FLOAT: float,
    ParameterType.BOOL: bool,
}


class APIToolsBean(BaseModel):
    server: str = Field(default="", validate_default=True)
    description: str = Field(default="", validate_default=True)
    paths: dict = Field(default_factory=dict, validate_default=True)

    @field_validator("server")
    def validator_server(cls, server: str):
        if not server or server == "":
            raise ValidateErrorException(message="server地址不能为空")
        return server

    @field_validator("description")
    def validator_description(cls, description: str):
        if not description or description == "":
            raise ValidateErrorException(message="description不能为空")
        return description

    @field_validator("paths")
    def validator_paths(cls, paths: dict[str, dict]):
        if not paths or not isinstance(paths, dict):
            raise ValidateErrorException(message="paths参数不能为空或者必须为字典")
        interface = []
        methods = ["get", "post"]
        extra_paths = {}
        for path, path_item in paths.items():
            for method in methods:
                if method in path_item:
                    interface.append({
                        "path": path,
                        "methods": method,
                        "operation": path_item[method]
                    })

        operation_ids = []
        for interface in interface:
            if not isinstance(interface["operation"].get("description"), str):
                raise ValidateErrorException(message="description参数不能为空")
            elif not isinstance(interface["operation"].get("operationId"), str):
                raise ValidateErrorException(message="operationId参数不能为空")
            elif not isinstance(interface["operation"].get("parameters", []), list):
                raise ValidateErrorException(message="parameters参数类型错误，必须数组")
            if interface["operation"]["operationId"] in operation_ids:
                raise ValidateErrorException(message="operationId不能重复")
            operation_ids.append(interface["operation"].get("operationId"))
            print(ParameterIn.__members__.values())
            for parameters_item in interface["operation"].get("parameters", []):
                if not isinstance(parameters_item.get("name"), str):
                    raise ValidateErrorException(message="parameters.name参数必须为字符串，并且不能为空")
                if (
                        not isinstance(parameters_item.get("in"), str)
                        or parameters_item["in"] not in ParameterIn.__members__.values()
                ):
                    raise ValidateErrorException(message=
                                                 f"parameter.in参数必须为{'/'.join([item.value for item in ParameterIn])}"
                                                 )
                if (
                        not isinstance(parameters_item.get("type"), str)
                        or parameters_item["type"] not in ParameterType.__members__.values()
                ):
                    raise ValidateErrorException(message=
                                                 f"parameter.type参数必须为{'/'.join([item.value for item in ParameterType])}"
                                                 )
                if not isinstance(parameters_item.get("description"), str):
                    raise ValidateErrorException(message="parameters.description参数必须为字符串，并且不能为空")
                if not isinstance(parameters_item.get("required"), bool):
                    raise ValidateErrorException(message="parameters.required参数必须为字bool，并且不能为空")
            extra_paths[interface["path"]] = {
                interface["methods"]: {
                    "description": interface["operation"]["description"],
                    "operationId": interface["operation"]["operationId"],
                    "parameters": [
                        {
                            "name": item.get("name"),
                            "in": item.get("in"),
                            "description": item.get("description"),
                            "required": item.get("required"),
                            "type": item.get("type")
                        } for item in interface["operation"].get("parameters", [])
                    ]
                }
            }
        return extra_paths
